#include<iostream>
#include<map>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define PATH "./wwwroot/root.html"
class Http{
    public:
        Http(){}
        std::string Serialization(){//序列化
            std::string request;
            request.append("GET http://www.google.com/ HTTP/1.0\r\n");
            for(const auto& e:_headers){
                request.append(e.first + ": " + e.second + "\r\n");
            }
            request.append("\r\n");
            request.append(_message);
            return request;
        }
        std::string Read(const std::string& path){
            std::string npath=(std::string)PATH+path;std::cout<<npath<<std::endl;
            std::string txt;
            int fd=open(npath.c_str(),O_RDONLY);
            if(fd==-1){
                txt.append("404 Not Found");
                return txt;
            }
            char buffer[1024];
            int n=0;
            while((n=read(fd,buffer,1024))>0){
                txt.append(buffer,n);
            }
            close(fd);
            return txt;
        }
        std::string Response(){
            std::string response;
            std::string txt=Read(_inbuffer_headers["path"]);
            int status=200;
            if(txt=="404 Not Found"){
                response.append("HTTP/1.0 404 Not Found\r\n");
            }
            else{
                response.append("HTTP/1.0 ");
                response.append(std::to_string(status));
                response.append(" OK\r\n");
            }
            _headers["Content-Type"] = "text/html; charset=UTF-8";  // 增加字符编码声明
            _headers["Content-Length"]=std::to_string(txt.size());
            for(const auto& e:_headers){
                response.append(e.first + ": " + e.second + "\r\n");
            }
            response.append("\r\n");
            response.append(txt);
            std::cout<<response<<std::endl;
            return response;
        }
        void Split() {//分割报文
            std::string ts; _inbuffer_headers.clear();
            int it = _message.find("\r\n");
            ts = _message.substr(0, it);
            bool y = false; std::string inbuffer;
            _message.erase(0, it + 2);
            for (int i = 0; i < ts.size(); i++) {
                if (ts[i] == '/') {
                    y = true; continue;
                }
                if (y && ts[i] == ' ') {
                    break;
                }
                if (y) {
                    inbuffer.push_back(ts[i]);
                }
            }
            _inbuffer_headers["path"] = inbuffer;
            std::string key, value;
            int l = 0, r = _message.find("\r\n\r\n");
            while (l < r) {
                it = _message.find("\r\n",l);
                ts = _message.substr(l, it - l);
                int i = 0;
                while (ts[i] != ':') {
                    key.push_back(ts[i]);
                    i++;
                }
                i += 2;
                while (i < ts.size()) {
                    value.push_back(ts[i]);
                    i++;
                }
                _inbuffer_headers[key] = value;
                l = it + 2; key.clear(); value.clear();
            }
            _message.erase(0, it + 4);
            if(_inbuffer_headers.find("Content-Length")!=_inbuffer_headers.end()){
                int len = std::stoi(_inbuffer_headers["Content-Length"]);
                key = "txt";
                value = _message.substr(0, r);
                _message.erase(0, r);
                _inbuffer_headers[key] = value;
            }
        }
        std::string Deserialization() {//反序列化
            std::string ts;
            int len = 0;//Data length
            size_t it = _message.find("\r\n\r\n"), it2 = _message.find("Content-Length");
            if(it2==std::string::npos){
                len=0;
            }
            else{
                std::string str_len;
                for (int i = it2 + 16; i < _message.size(); i++) {
                    if (_message[i] != '\r' && _message[i] != '\n') {
                        str_len.push_back(_message[i]);
                    }
                    else {
                        break;
                    }
                }
                std::cout<<str_len<<std::endl;
                len=std::stoi(str_len);
            }
            if (it == -1 || _message.size() - it - 3 < len) {
                return "";
            }
            Split();
            return _message;
        }
        void AddMessage(const std::string& message){
            _message+=message;
            //std::cout<<_message<<std::endl;
        }
        bool AddHeader(const std::string& key,const std::string& value){
            //这里要做检查是否合法的key和value
            _headers[key]=value;
            return true;
        }

    private:
        std::string _message;
        std::map<std::string,std::string> _headers;
        std::map<std::string,std::string> _inbuffer_headers;
};